package com.linln.admin.pcs.api;

import com.linln.admin.config.IDCardEncryptor;
import com.linln.admin.config.JwtTokenUtil;
import com.linln.admin.config.SmsUtils;
import com.linln.admin.pcs.service.RsaService;
import com.linln.admin.pcs.service.TemplateMessageService;
import com.linln.common.data.PageSort;
import com.linln.common.data.QuerySpec;
import com.linln.common.utils.DateUtils;
import com.linln.common.utils.EncryptUtil;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.vo.ResultVo;
import com.linln.modules.system.domain.*;
import com.linln.modules.system.repository.*;
import com.linln.modules.system.service.OrderAmountsService;
import com.linln.modules.system.service.OrderPortersService;
import com.linln.modules.system.service.SmsLogService;
import io.swagger.annotations.ApiParam;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.transaction.Synchronization;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * 护工端
 */
@RestController
@RequestMapping("/api/porter/")
public class PorterApiController {
    private final static Logger logger = LoggerFactory.getLogger(PorterApiController.class);
    @Value("${securitys.hgKey}")
    private  String SECRET_KEY;

    @Autowired
    private PorterRepository porterRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private OrderLogsRepository orderLogsRepository;

    @Autowired
    private MsgRepository msgRepository;

    @Autowired
    private PorterCredentialsRepository porterCredentialsRepository;

    @Autowired
    private EvaluateRepository evaluateRepository;

    @Autowired
    private PorterPermissionRepository porterPermissionRepository;

    @Autowired
    private OrderPortersService orderPortersService;

    @Autowired
    private OrderPortersRepository orderPortersRepository;

    @Autowired
    private PatientAdmissionRepository patientAdmissionRepository;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private OrderAmountsService orderAmountsService;

    private final Lock lock = new ReentrantLock();

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private TemplateMessageService templateMessageService;

    @Autowired
    private PatientRepository patientRepository;

    @Autowired
    private SmsLogService smsLogService;
    /**
     * 护工登录
     */
    @PostMapping("login")
    public ResultVo porterDetail(@RequestBody Porter porters) {
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherValue("name", QuerySpec.EQUAL,porters.getName());
        List<Porter> porterList = porterRepository.findAll(QuerySpec.of(querySpec));
        if (porterList.size()>0){
            Porter porter = porterList.get(0);
            String password = porter.getPassword();
            // 对明文密码加密处理
            String encrypt = EncryptUtil.encrypt(porters.getPassword(), "qfB6mY");
            if (password.equals(encrypt)){
                //查询所有护理科室
                QuerySpec querySpec2 = QuerySpec.matching();
                querySpec2.withMatcherValue("status", QuerySpec.EQUAL,"1")
                        .withMatcherValue("verifyStatus", QuerySpec.EQUAL,"1")
                        .withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(porter.getId()));
                List<PorterPermission> permissionList = porterPermissionRepository.findAll(QuerySpec.of(querySpec2));
                porter.setPorterPermissions(permissionList);
                porter.setCardNo(IDCardEncryptor.aesTuoMinDecrypt(porter.getCardNo()));
                porter.setPhone(IDCardEncryptor.aesTuoMinPhoneDecrypt(porter.getPhone()));

                String token = jwtTokenUtil.generateToken(porter.getName(),SECRET_KEY);
                Map<String, Object> result = new HashMap<>();
                result.put("token", token);
                result.put("porter", porter);
                return ResultVoUtil.success("登录成功",result);
            }else {
                return ResultVoUtil.error("密码错误");
            }
        }
        return ResultVoUtil.error("用户名错误");
    }

    /**
     * 首页统计护工服务数量
     * @param id
     * @return
     */
    @RequestMapping("statistics")
    public ResultVo statistics(@RequestParam long id){
        QuerySpec querySpec = QuerySpec.matching();
        List<Object> statusList = new ArrayList<>();
        statusList.add(2);
        querySpec.withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(id))
                .withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherIn("serviceStatus",statusList);
        List<OrderPorters> orderList = orderPortersRepository.findAll(QuerySpec.of(querySpec));
        Map<String,Integer> map = new HashMap<>();
        //定义陪护 陪检
        int serviceNumber = 0;
        int checkNumber = 0;
        if (orderList.size()>0) {
            for (OrderPorters order : orderList){
                switch (order.getOrderType()){
                    case 1:
                        serviceNumber++;
                        break;
                    case 2:
                    case 3:
                        checkNumber++;
                        break;
                }
            }
        }
        map.put("serviceNumber",serviceNumber);
        map.put("checkNumber",checkNumber);
        return ResultVoUtil.success("统计护工服务数量",map);
    }

    /**
     * 护工服务列表
     * @param id
     * @return
     */
    @RequestMapping("order/list")
    public ResultVo orderList(@RequestParam long id,@RequestParam int type){
        QuerySpec querySpec = QuerySpec.matching();
        List<Object> typeList = new LinkedList<>();
        List<Object> statusList = new LinkedList<>();
        if (type==1){
            typeList.add(1);
            statusList.add(2);
        }else{
            typeList.add(2);
            typeList.add(3);
            statusList.add(2);
            statusList.add(3);
        }
        //查询历史订单
        querySpec.withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherValue("payStatus", QuerySpec.EQUAL,"1")
                .withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(id))
                .withMatcherIn("orderStatus",statusList)
                .withMatcherIn("type", typeList);
        PageRequest pageRequest = PageSort.pageRequest(1, "startDay", Sort.Direction.DESC);
        Page<Order> all = orderRepository.findAll(QuerySpec.of(querySpec), pageRequest);
        List<Order> orderList = all.getContent();
        for (Order order : orderList){
            int type1 = order.getType();
            if (type1==1){
                PatientAdmission patientAdmission = patientAdmissionRepository.findById(order.getPatientAdmissionId()).get();
                String admissionTime = patientAdmission.getAdmissionTime();
                Date date = DateUtils.parseStrToDate("yyyy-MM-dd", admissionTime);
                String s = DateUtils.parseDateToStr("yyyy/MM/dd", date);
                order.setStartDay(s);
            }else{
                String startDay = order.getStartDay();
                if (StringUtils.isNotEmpty(startDay)){
                    Date date = DateUtils.parseStrToDate("yyyy-MM-dd", startDay);
                    String s = DateUtils.parseDateToStr("yyyy/MM/dd", date);
                    order.setStartDay(s);
                }
            }
            if(order.getAdmissionTime()!=null&&!order.getAdmissionTime().equals("")){
                Date date = DateUtils.parseStrToDate("yyyy-MM-dd", order.getAdmissionTime());
                order.setAdmissionTimeStr( DateUtils.parseDateToStr("MM/dd",date));
            }
        }
        Map<String,Object> map = new HashMap<>();
        map.put("totalPages",all.getTotalElements());
        map.put("list",orderList);
        return ResultVoUtil.success("护工服务列表",map);
    }

    /**
     * 护工服务详情
     * @param id
     * @return
     */
    @RequestMapping("order/detail")
    public ResultVo orderDetail(@RequestParam String id){
        Order order = orderRepository.findById(Long.valueOf(id)).get();
        int type = order.getType();
        //服务日志
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("orderId", QuerySpec.EQUAL, id);
        List<OrderLogs> orderLogList = orderLogsRepository.findAll(QuerySpec.of(querySpec),Sort.by(Sort.Direction.ASC,"createDay"));
        List<Map<String,List<OrderLogs>>> list= new LinkedList<>();
        if (orderLogList.size()>0){
            String createDay1 = orderLogList.get(0).getCreateDay();
            int m = 0;
            for (int i=0;i<orderLogList.size();i++){
                Map<String,List<OrderLogs>> hs = new HashMap<>();
                List<OrderLogs> orderLogsList = new LinkedList<>();
                for (;m<orderLogList.size();){
                    OrderLogs orderLogs = orderLogList.get(m);
                    String createDay = orderLogs.getCreateDay();
                    if (StringUtils.isNotEmpty(createDay)&&createDay1.equals(createDay)){
                        String s = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderLogs.getCreateTime());
                        String[] s1 = s.split(" ");
                        orderLogs.setTimes(s1[1]);
                        orderLogsList.add(orderLogs);
                        m++;
                    }else{
                        hs.put(createDay1,orderLogsList);
                        createDay1 = createDay;
                        break;
                    }
                }
                if (m==orderLogList.size()){
                    //最后一个补充上去
                    hs.put(createDay1,orderLogsList);
                    list.add(hs);
                    break;
                }else{
                    list.add(hs);
                }
            }
        }
        order.setMapOrderLogsList(list);
        if (StringUtils.isNotEmpty(order.getPhone())){
            order.setPhone(IDCardEncryptor.aesTuoMinPhoneDecrypt(order.getPhone()));
        }
        return ResultVoUtil.success("护工服务详情",order);
    }

    /**
     * 抢单大厅列表
     * @param id
     * @return
     */
    @RequestMapping("wait/order/list")
    public ResultVo waitOrderList(@RequestParam long id){
        Porter porter = porterRepository.getById(id);
        QuerySpec querySpec = QuerySpec.matching();
        List<Object> typeList = new LinkedList<>();
        typeList.add(2);
        typeList.add(3);
        //查询历史订单
        querySpec.withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherValue("payStatus", QuerySpec.EQUAL,"1")
                .withMatcherValue("orderStatus",QuerySpec.EQUAL,"0")
                .withMatcherValue("companyId",QuerySpec.EQUAL,String.valueOf(porter.getCompanyId()))
                .withMatcherIn("type", typeList);
        PageRequest pageRequest = PageSort.pageRequest(1, "id", Sort.Direction.DESC);
        Page<Order> all = orderRepository.findAll(QuerySpec.of(querySpec), pageRequest);
        List<Order> orderList = all.getContent();

        Map<String,Object> map = new HashMap<>();
        map.put("totalPages",all.getTotalElements());
        map.put("list",orderList);
        return ResultVoUtil.success("待接单列表",map);
    }

    /**
     * 接单
     * @param order
     * @return
     */
    @PostMapping("order/taking")
    @Transactional(rollbackFor = Exception.class)
    public  ResultVo orderTaking(@RequestBody Order order){
        String lockKey = "porterTakingLock"+order.getId();
        Boolean isLocked = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS);
        if (isLocked != null && isLocked) {
            try {
                Porter porter = porterRepository.getById(order.getPorterId());
                Order info = orderRepository.findById(order.getId()).get();
                int orderStatus = info.getOrderStatus();
                if (orderStatus==0){
                    //判断是否需要签订合同
                    Byte isNeedSignContract = info.getIsNeedSignContract();
                    if (isNeedSignContract==1){
                        info.setOrderStatus(1);
                    }else{
                        info.setOrderStatus(2);
                        //扣除费用
                        info.setNum(1);
                        info.setTotal(info.getPrice());
                        //更新记录
                        orderPortersService.updatePorterOrder(info.getId(),order.getPorterId(),0L,info.getCompanyId(),1,info.getStartDay(),"",1,info.getType());
                        //金额变动表
                        orderAmountsService.updateOrderAmounts(info,"患者费用扣除",1);
                    }
                    info.setPorterId(porter.getId());
                    info.setPorterName(porter.getName());
                    info.setPorterPhone(porter.getPhone());

                    //新增消息通知
                    Msg msg = new Msg();
                    msg.setPatientId(info.getPatientId());
                    msg.setType((byte) 1);
                    String msgs = "";
                    int type = info.getType();
                    if (type==2){
                        msgs = "陪诊";
                    }else {
                        msgs = "陪检";
                    }
                    msg.setSn(info.getSn());
                    msg.setContent("您的"+msgs+"订单已被成功接单!您将有专属的陪护员为您提供全程陪伴与协助服务.");
                    msgRepository.save(msg);

                    orderRepository.save(info);
                    try {
                        Patient patient = patientRepository.findById(info.getPatientId()).get();
                        String contents = "您的"+info.getProjectTitle()+"项目已接单";
                        if (StringUtils.isNotEmpty(patient.getPhone())){
                            String ss = IDCardEncryptor.aesDecrypt(patient.getPhone());
                            String resp = SmsUtils.sendSms(ss, contents);
                            logger.error("接单消息发送结果："+resp);
                            smsLogService.insert(order.getSn(),patient.getPhone(),4,3,patient.getId(),contents,resp);
                        }else{
                            smsLogService.insert(order.getSn(),patient.getPhone(),4,3,patient.getId(),contents,"发送失败,手机号为空");
                        }
                    } catch (Exception e) {
                        logger.error("已接单消息发送失败"+e.getMessage());
                    }
                    return ResultVoUtil.success("接单成功",info);
                }else{
                    return ResultVoUtil.error("订单已接");
                }
            } finally {
                // 删除锁
                redisTemplate.delete(lockKey);
            }
        } else {
            return ResultVoUtil.error("订单已接");
        }
    }

    /**
     * 开始服务(废弃)
     * @param order
     * @return
     */
    @PostMapping("start/service")
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResultVo startService(@RequestBody Order order){
        Order info = orderRepository.findById(order.getId()).get();
        info.setOrderStatus(2);
        String dates = DateUtils.getDates();
        info.setStartDay(dates);
        orderRepository.save(info);
        //更新记录
        orderPortersService.updatePorterOrder(info.getId(),info.getPorterId(),0L,info.getCompanyId(),1,info.getStartDay(),"",1,info.getType());
        return ResultVoUtil.success("开始服务",info);
    }

    /**
     * 记录服务
     * @param orderLogs
     * @return
     */
    @PostMapping("record/service")
    @Transactional(rollbackFor = Exception.class)
    public ResultVo recordService(@RequestBody OrderLogs orderLogs){
        Porter porter = porterRepository.getById(orderLogs.getPorterId());
        orderLogs.setPorterName(porter.getName());
        orderLogs.setPorterImg(porter.getHeadimg());
        String day = DateUtils.getDate();
        //判断今天记录了几次  一天最多记录三次
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("orderId", QuerySpec.EQUAL,String.valueOf(orderLogs.getOrderId()))
                .withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(orderLogs.getPorterId()))
                .withMatcherValue("createDay", QuerySpec.EQUAL,day)
                .withMatcherValue("status", QuerySpec.EQUAL,"1");
        List<OrderLogs> logsList = orderLogsRepository.findAll(QuerySpec.of(querySpec));
        if (logsList.size()>=3){
            return ResultVoUtil.error("一天最多记录三次");
        }else{
            orderLogs.setCreateDay(day);
            orderLogs.setStatus((byte) 1);
            orderLogsRepository.save(orderLogs);
            return ResultVoUtil.success("记录服务",orderLogs);
        }
    }

    /**
     * 统计服务数据
     * @param id
     * @return
     */
    @RequestMapping("statistics/service")
    public ResultVo statisticsService(@RequestParam String id){
        QuerySpec querySpec = QuerySpec.matching();
        //查询历史订单记录
        List<Object> statusList = new ArrayList<>();
        statusList.add(2);
        querySpec.withMatcherValue("porterId", QuerySpec.EQUAL,id)
                .withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherIn("serviceStatus",statusList);
        List<OrderPorters> orderList = orderPortersRepository.findAll(QuerySpec.of(querySpec));
        List<Integer> typeList = new LinkedList<>();
        //定义服务次数
        int allServiceNumber = 0;
        int serviceNumber = 0;
        int pzNumber = 0;
        int pjNumber = 0;
        for (OrderPorters order : orderList) {
            int type = order.getOrderType();
            if (type==1){
                serviceNumber++;
                allServiceNumber++;
            }else if (type==2){
                pzNumber++;
                allServiceNumber++;
            }else if (type==3){
                pjNumber++;
                allServiceNumber++;
            }
        }
        typeList.add(allServiceNumber);
        typeList.add(serviceNumber);
        typeList.add(pzNumber);
        typeList.add(pjNumber);
        return ResultVoUtil.success("统计服务数据",typeList);
    }

    /**
     * 个人资料
     */
    @GetMapping("detail")
    public ResultVo porterDetail(@RequestParam("id") String id) {
        Porter info = porterRepository.findById(Long.valueOf(id)).get();

        //查询技能证书
        QuerySpec querySpec2 = QuerySpec.matching();

        //获取当前时间
        Date dates = DateUtils.getNowDate();

        querySpec2.withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(info.getId()))
                .withMatcherValue("status", QuerySpec.EQUAL,"1");

        List<PorterCredentials> credentialsList = porterCredentialsRepository.findAll(QuerySpec.of(querySpec2));
        List<PorterCredentials> credentialsLists = new LinkedList<>();
        for (PorterCredentials porterCredentials : credentialsList) {
            if (ObjectUtils.isNotEmpty(porterCredentials.getExpireDate())){
                int compare = DateUtils.compare(porterCredentials.getExpireDate(), dates);
                if (compare == 1){
                    credentialsLists.add(porterCredentials);
                }
            }
        }
        //查询所有护理科室
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherValue("verifyStatus", QuerySpec.EQUAL,"1")
                .withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(info.getId()));
        List<PorterPermission> permissionList = porterPermissionRepository.findAll(QuerySpec.of(querySpec2));
        info.setPorterPermissions(permissionList);
        info.setCredentials(credentialsLists);
        info.setPhone(IDCardEncryptor.aesTuoMinPhoneDecrypt(info.getPhone()));
        return ResultVoUtil.success("个人资料",info);
    }

    /**
     * 陪护、陪诊陪检记录
     */
    @GetMapping("service/history")
    public ResultVo service(@RequestParam("id") Long id,@RequestParam("type") int type) {
        QuerySpec querySpec = QuerySpec.matching();
        List<Object> typeList = new LinkedList<>();
        if (type==1){
            typeList.add(1);
        }else{
            typeList.add(2);
            typeList.add(3);
        }
        //查询历史订单
        querySpec.withMatcherValue("status", QuerySpec.EQUAL,"1")
                .withMatcherValue("payStatus", QuerySpec.EQUAL,"1")
                .withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(id))
                .withMatcherValue("orderStatus", QuerySpec.GT,"4")
                .withMatcher("patientName", QuerySpec.LIKE)
                .withMatcherIn("type", typeList);
        PageRequest pageRequest = PageSort.pageRequest(1, "id", Sort.Direction.DESC);
        Page<Order> all = orderRepository.findAll(QuerySpec.of(querySpec), pageRequest);
        List<Order> orderList = all.getContent();

        Map<String,Object> map = new HashMap<>();
        map.put("totalPages",all.getTotalElements());
        map.put("list",orderList);
        return ResultVoUtil.success("陪护记录",map);
    }

    /**
     * 查看评价
     */
    @GetMapping("check/evaluate")
    public ResultVo checkEvaluate(@RequestParam String sn){
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("sn", QuerySpec.EQUAL,sn)
                .withMatcherValue("status", QuerySpec.EQUAL,String.valueOf(1));
        List<Evaluate> evaluateList = evaluateRepository.findAll(QuerySpec.of(querySpec));
        if (evaluateList.size()>0){
            Evaluate evaluate = evaluateList.get(0);
            evaluate.setCreateTimeStr(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,evaluate.getCreateTime()));
            return ResultVoUtil.success("评价详情",evaluate);
        }else{
            return ResultVoUtil.error("未评价");
        }
    }

    /**
     * 记录详情(同护工服务详情)
     */
//    @GetMapping("order/detail")
//    public ResultVo orderDetail(@RequestParam Long id) {
//        Order order = orderRepository.findById(id).get();
//        //服务日志
//        QuerySpec querySpec = QuerySpec.matching();
//        querySpec.withMatcherValue("orderId", QuerySpec.EQUAL,String.valueOf(id));
//        List<OrderLogs> orderLogList = orderLogsRepository.findAll(QuerySpec.of(querySpec),Sort.by(Sort.Direction.DESC,"id"));
//        order.setOrderLogList(orderLogList);
//        return ResultVoUtil.success("记录详情",order);
//    }

}
